package com.wanqing.community.util;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.log4j.Logger;

import net.sf.ezmorph.object.DateMorpher;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import net.sf.json.util.JSONUtils;

public class ObjectTools {
	
	private static Logger log = Logger.getLogger(ObjectTools.class);

	/**
	 * <p>Description:将Map中的值封装到一个业务类中，<br/>并且Map中的Key必须要与业务对象的属性相同但不区分大小写<p>
	 * <p>modifiContent:<p>
	 * @param obj 业务类的对象
	 * @param map 要取值Map
	 */
	public static void setMapToObject(Object obj, Map<String, Object> map) {
		try {
			Class<?> objc = obj.getClass();
			if (null != map && !map.isEmpty()) {
				Set<String> sets = map.keySet();
				Field[] fs = objc.getDeclaredFields();
				for (Field f : fs) {
					f.setAccessible(true);
					String fname = f.getName();
					String type = f.getType().getSimpleName();
					for (String key : sets) {						
						Object value = map.get(key);
						if (key.equalsIgnoreCase(fname)) {
							if (type.equals("String")) {
								f.set(obj, StringTools.objectToString(value));
							} else if (type.equals("int")) {
								f.set(obj, NumberDealTools.objectToInt(value));
							}else if("Integer".equals(type)){
								f.set(obj, NumberDealTools.objectToInteger(value));
							}else if (type.equals("double")) {
								f.set(obj, NumberDealTools.objectTodouble(value));
							}else if("Double".equals(type)){
								f.set(obj, NumberDealTools.objectToDouble(value));
							}else if (type.equals("long")) {
								f.set(obj, NumberDealTools.objectTolong(value));
							}else if("Long".equals(type)){
								f.set(obj, NumberDealTools.objectToLong(value));
							}else if (type.equals("float")) {
								f.set(obj, NumberDealTools.objectTofloat(value));
							}else if("Float".equals(type)){
								f.set(obj, NumberDealTools.objectToFloat(value));
							}else{
								f.set(obj, value);
							}
						}
					}
				}
			}
		} catch (Exception e) {
			log.error("setMapToBean异常："+e.toString());
		}
	}
	
	/**
	 * <p>Description:将Map中的值封装到一个业务类中，<br/>并且Map中的Key必须要与业务对象的属性相同但不区分大小写<p>
	 * <p>modifiContent:<p>
	 * @param obj 业务类的对象
	 * @param map 要取值Map
	 */
	public static <T> T setMapToObject(Class<T> c,Map<String, Object> map){
		if(null==map || map.isEmpty()){
			return null;
		}
		T t = null;
		try{
			t = c.newInstance();
			Set<String> kyes = map.keySet();
			Field[] fs = c.getDeclaredFields();
			for (Field f : fs) {
				f.setAccessible(true);
				String fname = f.getName();
				String type = f.getType().getSimpleName();				
				for (String key : kyes) {					
					Object value = map.get(key);
					if (key.equalsIgnoreCase(fname)) {
						if (type.equals("String")) {
							f.set(t, StringTools.objectToString(value));
						} else if (type.equals("int")) {
							f.set(t, NumberDealTools.objectToInt(value));
						}else if("Integer".equals(type)){
							f.set(t, NumberDealTools.objectToInteger(value));
						}else if (type.equals("double")) {
							f.set(t, NumberDealTools.objectTodouble(value));
						}else if("Double".equals(type)){
							f.set(t, NumberDealTools.objectToDouble(value));
						}else if (type.equals("long")) {
							f.set(t, NumberDealTools.objectTolong(value));
						}else if("Long".equals(type)){
							f.set(t, NumberDealTools.objectToLong(value));
						}else if (type.equals("float")) {
							f.set(t, NumberDealTools.objectTofloat(value));
						}else if("Float".equals(type)){
							f.set(t, NumberDealTools.objectToFloat(value));
						}else{
							f.set(t, value);
						}
					}
				}
			}
		}catch (Exception e) {
			log.error("setMapToObject===>Class<T> c异常："+e.toString());
		}		
		return t;
	}
	
	/**
	 * <p>Description:将Map中的值封装到一个业务类中，<br/>并且Map中的Key必须要与业务对象的属性相同但不区分大小写<p>
	 * <p>modifiContent:<p>
	 * @param obj 业务类的对象
	 * @param map 要取值Map
	 */
	public static void mapToObject(Object obj, Map<String, String> map) {
		try {
			Class<?> objc = obj.getClass();
			if (null != map && !map.isEmpty()) {
				Set<String> sets = map.keySet();
				Field[] fs = objc.getDeclaredFields();
				for (Field f : fs) {
					f.setAccessible(true);
					String fname = f.getName();
					String type = f.getType().getSimpleName();
					for (String key : sets) {
						String value = StringTools.objectToString(map.get(key));
						if (key.equalsIgnoreCase(fname)) {
							if (type.equals("String")) {
								f.set(obj, StringTools.objectToString(value));
							} else if (type.equals("int")) {
								f.set(obj, NumberDealTools.objectToInt(value));
							}else if("Integer".equals(type)){
								f.set(obj, NumberDealTools.objectToInteger(value));
							}else if (type.equals("double")) {
								f.set(obj, NumberDealTools.objectTodouble(value));
							}else if("Double".equals(type)){
								f.set(obj, NumberDealTools.objectToDouble(value));
							}else if (type.equals("long")) {
								f.set(obj, NumberDealTools.objectTolong(value));
							}else if("Long".equals(type)){
								f.set(obj, NumberDealTools.objectToLong(value));
							}else if (type.equals("float")) {
								f.set(obj, NumberDealTools.objectTofloat(value));
							}else if("Float".equals(type)){
								f.set(obj, NumberDealTools.objectToFloat(value));
							}
						}
					}
				}
			}
		} catch (Exception e) {
			log.error("mapToBean异常："+e.toString());
		}
	}
	
	/**
	 * <p>Description:将Map中的值封装到一个业务类中，<br/>并且Map中的Key必须要与业务对象的属性完全一致才能封装<p>
	 * <p>modifiContent:<p>
	 * @param <T>
	 * @param c 业务对象 格式为：业务类.class
	 * @param map 要取值Map
	 * @return
	 */
	public static <T> T mapToObject(Class<T> c,Map<String, Object> map){
		T t = null;
		try{
			t = c.newInstance();
			Set<String> kyes = map.keySet();
			for (String key : kyes) {
				String fileName = key;
				Object value = map.get(key);
				Method get_Method = c.getMethod("get" + StringTools.firstLetterUpperCase(fileName));
				Method set_Method = c.getMethod("set" + StringTools.firstLetterUpperCase(fileName), get_Method.getReturnType());
				Class<?> clazz = get_Method.getReturnType();
				String type = clazz.getSimpleName();				
				if("long".equals(type)){
					set_Method.invoke(t, NumberDealTools.objectTolong(value));
				}else if("Long".equals(type)){
					set_Method.invoke(t, NumberDealTools.objectToLong(value));
				}else if("int".equals(type)){
					set_Method.invoke(t, NumberDealTools.objectToInt(value));
				}else if("Integer".equals(type)){
					set_Method.invoke(t, NumberDealTools.objectToInteger(value));
				}else if("String".equals(type)){
					set_Method.invoke(t,StringTools.objectToString(value));
				}else if("double".equals(type)){
					set_Method.invoke(t, NumberDealTools.objectTodouble(value));
				}else if("Double".equals(type)){
					set_Method.invoke(t, NumberDealTools.objectToDouble(value));
				}else if("float".equals(type)){
					set_Method.invoke(t, NumberDealTools.objectTofloat(value));
				}else if("Float".equals(type)){
					set_Method.invoke(t, NumberDealTools.objectToFloat(value));
				}else{
					set_Method.invoke(t, c.cast(value));
				}
			}
		}catch (Exception e) {
			
		}
		return t;
	}
	
	public static Map<String, Object> objectToMap(Object obj) {
		Map<String, Object> map = new HashMap<String, Object>();
		try {
			Class<?> objc = obj.getClass();
			Field[] fs = objc.getDeclaredFields();
			for (Field field : fs) {
				field.setAccessible(true);
				String type = field.getType().getSimpleName();
				String fname = field.getName();
				if(type.equals("int") || type.equals("Integer")){
					map.put(fname, field.getInt(fname));
				}else if(type.equals("double") || type.equals("Double")){
					map.put(fname, NumberDealTools.objectToDouble(field.get(fname)));
				}else if(type.equals("float") || type.equals("Float")){
					map.put(fname, NumberDealTools.objectTofloat(field.get(fname)));
				}else{
					map.put(fname, field.get(fname));
				}
			}
		} catch (Exception e) {
			log.error("objectToMap异常："+e.toString());
		}
		return map;
	}
	
	/**
	 * <p>Description:将JSON串转为指定的对象<p>
	 * <p>modifiContent:<p>
	 * @param <T>
	 * @param content
	 * @param requiredType
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static <T> T jsonStrToObject(String content,Class<T> requiredType){
		JSONObject jsonObject = JSONObject.fromObject(content);
		return (T) JSONObject.toBean(jsonObject, requiredType);
	}
	
	/**
	 * <p>Description:将JSON串转为指定的对象<p>
	 * <p>modifiContent:<p>
	 * @param <T>
	 * @param content
	 * @param requiredType
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static <T> T jsonStrToObject(String content,String key,Class<T> requiredType){
		JSONObject jsonObject = JSONObject.fromObject(content);
		return (T) JSONObject.toBean(jsonObject.getJSONObject(key), requiredType);
	}
	
	/**
	 * <p>Description:将JSON串转为指定的对象<p>
	 * <p>modifiContent:<p>
	 * @param <T>
	 * @param content
	 * @param requiredType
	 * @return
	 */
	public static <T> T jsonStrToObject(HttpServletRequest request,Class<T> requiredType){
		String requeststr = JsonUtil.getRequestJson(request);		
		//把json转换为Bean
		return jsonStrToObject(requeststr, requiredType);
	}
	
	/**
	 * <p>Description:将JSON串转为指定的对象<p>
	 * <p>modifiContent:<p>
	 * @param <T>
	 * @param content
	 * @param requiredType
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static <T> T jsonStrToObject(HttpServletRequest request,String key,Class<T> requiredType){
		String requeststr = JsonUtil.getRequestJson(request);		
		//将json数据串转为JSONObject对象
		JSONObject jsonObject = JSONObject.fromObject(requeststr);		
		//把json转换为Bean
		return (T) JSONObject.toBean(jsonObject.getJSONObject(key), requiredType);
	}
	
	/**
	 * <p>Description:将JSON串转为Map<p>
	 * <p>modifiContent:<p>
	 * @param request
	 * @param key
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static Map<String,String> jsonStrToMap(String content){
		return jsonStrToObject(content, Map.class);
	}
	
	/**
	 * <p>Description:将JSON串转为Map<p>
	 * <p>modifiContent:<p>
	 * @param request
	 * @param key
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static Map<String,String> jsonStrToMap(String content,String key){
		return jsonStrToObject(content,key, Map.class);
	}
	
	/**
	 * <p>Description:将JSON串转为Map<p>
	 * <p>modifiContent:<p>
	 * @param request
	 * @param key
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static Map<String,String> jsonStrToMap(HttpServletRequest request,String key){
		return jsonStrToObject(request, key, Map.class);
	}
	
	/**
	 * <p>Description:将JSON串转为集合<p>
	 * <p>modifiContent:<p>
	 * @param <T>
	 * @param jsonContent
	 * @param requiredType
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static <T> List<T> jsonStrToList(String jsonContent,Class<T> requiredType){
		setDataFormat2JAVA();
		JSONArray array = JSONArray.fromObject(jsonContent);
		List<T> list = new ArrayList<T>();
		for(Iterator iter = array.iterator(); iter.hasNext();){
			JSONObject jsonObject = (JSONObject)iter.next();
			list.add((T) JSONObject.toBean(jsonObject, requiredType));
		}
		return list;
	}
	
	/**
	 * <p>Description:将JSON串转为集合<p>
	 * <p>modifiContent:<p>
	 * @param <T>
	 * @param jsonContent 
	 * @param key JSON串的起始键
	 * @param requiredType
	 * @return
	 */
	public static <T> List<T> jsonStrToList(String jsonContent,String key,Class<T> requiredType){
		JSONObject jsonObject = JSONObject.fromObject(jsonContent);
		String temp = jsonObject.getString(key);
		if(StringTools.isEmptyOrNull(temp)){
			return null;
		}		
		return jsonStrToList(temp,requiredType);
	}
	
	@SuppressWarnings("unchecked")
	public static List<Map> jsonStrToListMap(HttpServletRequest request,String key){
		return jsonStrToList(request, key, Map.class);
	}
	
	public static List<Properties> jsonStrToListProperties(HttpServletRequest request,String key){
		return jsonStrToList(request, key, Properties.class);
	}
	
	/**
	 * <p>Description:将JSON串转为集合<p>
	 * <p>modifiContent:<p>
	 * @param <T>
	 * @param jsonContent 
	 * @param key JSON串的起始键
	 * @param requiredType
	 * @return
	 */
	public static <T> List<T> jsonStrToList(JSONObject jsonObject,String key,Class<T> requiredType){		
		String temp = jsonObject.getString(key);
		if(StringTools.isEmptyOrNull(temp)){
			return null;
		}		
		return jsonStrToList(temp,requiredType);
	}
	
	/**
	 * <p>Description:将JSON串转为集合<p>
	 * <p>modifiContent:<p>
	 * @param <T>
	 * @param request
	 * @param requiredType
	 * @return
	 */
	public static <T> List<T> jsonStrToList(HttpServletRequest request,Class<T> requiredType){
		String jsonContent = JsonUtil.getRequestJson(request);
		return jsonStrToList(jsonContent,requiredType);
	}
	
	/**
	 * <p>Description:将JSON串转为集合<p>
	 * <p>modifiContent:<p>
	 * @param <T>
	 * @param request
	 * @param key JSON串的起始键
	 * @param requiredType
	 * @return
	 */
	public static <T> List<T> jsonStrToList(HttpServletRequest request,String key,Class<T> requiredType){
		String jsonContent = JsonUtil.getRequestJson(request);
		return jsonStrToList(jsonContent, key, requiredType);
	}
	
	/**
	 * <p>Description:JSON中日期转换格式<p>
	 * <p>modifiContent:<p>
	 */
	private static void setDataFormat2JAVA(){		
		JSONUtils.getMorpherRegistry().registerMorpher(new DateMorpher(new String[] {"yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss"}));
	}
	
	/**
	 * <p>Description:复制对象，将orig中的值赋给dest<p>
	 * <p>modifiContent:<p>
	 * @param orig 源对象
	 * @param dest 目标对象
	 */
	public static void copyObjects(Object orig,Object dest){
		try {
			BeanUtils.copyProperties(dest, orig);
		} catch (IllegalAccessException e) {			
			log.error("复制对象异常=>IllegalAccessException："+e.toString());
		} catch (InvocationTargetException e) {			
			log.error("复制对象异常=>InvocationTargetException："+e.toString());
		}
	}
}
